package com.star.langchain.learn.config;

import lombok.extern.slf4j.Slf4j;

import dev.langchain4j.data.message.AiMessage;
import dev.langchain4j.guardrail.OutputGuardrail;
import dev.langchain4j.guardrail.OutputGuardrailRequest;
import dev.langchain4j.guardrail.OutputGuardrailResult;

@Slf4j
public class SecondGuard implements OutputGuardrail {

    /**
     * Validates the response from the LLM.
     *
     * @param responseFromLLM the response from the LLM
     */
    public OutputGuardrailResult validate(AiMessage responseFromLLM) {
        log.info("=======================responseFromLLM:{}", responseFromLLM + "====================");
        return OutputGuardrailResult.success();
    }

    /**
     * Validates the response from the LLM.
     * <p>
     * Unlike {@link #validate(AiMessage)}, this method allows to access the memory and the augmentation result (in the
     * case of a RAG).
     * <p>
     * Implementation must not attempt to write to the memory or the augmentation result.
     *
     * @param request the parameters, including the response from the LLM, the memory, and the augmentation result.
     */
    @Override
    public OutputGuardrailResult validate(OutputGuardrailRequest request) {
        log.info("=======================validate:{}", request + "====================");
        return validate(request.responseFromLLM().aiMessage());
    }

    /**
     * Produces a successful result without any successful text
     *
     * @return The result of a successful output guardrail validation.
     */
    public OutputGuardrailResult success() {
        log.info("=======================success:====================");
        return OutputGuardrailResult.success();
    }

    /**
     * Produces a successful result with specific success text
     *
     * @param successfulText The text of the successful result.
     * @return The result of a successful output guardrail validation with a specific text.
     */
    public OutputGuardrailResult successWith(String successfulText) {
        log.info("=======================successWith:{}", successfulText + "====================");
        return OutputGuardrailResult.successWith(successfulText);
    }

    /**
     * Produces a non-fatal failure
     *
     * @param successfulText   The text of the successful result.
     * @param successfulResult The object generated by this successful result.
     * @return The result of a successful output guardrail validation with a specific text.
     */
    public OutputGuardrailResult successWith(String successfulText, Object successfulResult) {
        log.info("=======================successWith:{}", successfulText + "====================");
        return OutputGuardrailResult.successWith(successfulText, successfulResult);
    }

    /**
     * Produces a successful result with specific success text
     *
     * @param successfulAiMessage The AiMessage successful result.
     * @return The result of a successful output guardrail validation with a specific AiMessage.
     */
    public OutputGuardrailResult successWith(AiMessage successfulAiMessage) {
        log.info("=======================successWith:{}", successfulAiMessage + "====================");
        return OutputGuardrailResult.successWith(successfulAiMessage);
    }

    /**
     * Produces a non-fatal failure
     *
     * @param successfulAiMessage The AiMessage successful result.
     * @param successfulResult    The object generated by this successful result.
     * @return The result of a successful output guardrail validation with a specific AiMessage.
     */
    public OutputGuardrailResult successWith(AiMessage successfulAiMessage, Object successfulResult) {
        log.info("=======================successWith:{}", successfulAiMessage + "====================");
        return OutputGuardrailResult.successWith(successfulAiMessage, successfulResult);
    }

    /**
     * Produces a non-fatal failure
     *
     * @param message A message describing the failure.
     * @return The result of a failed output guardrail validation.
     */
    public OutputGuardrailResult failure(String message) {
        log.info("=======================failure:{}", message + "====================");
        return null;
    }

    /**
     * Produces a non-fatal failure
     *
     * @param message A message describing the failure.
     * @param cause   The exception that caused this failure.
     * @return The result of a failed output guardrail validation.
     */
    public OutputGuardrailResult failure(String message, Throwable cause) {
        log.info("=======================failure:{}", message + "====================");
        return null;
    }

    /**
     * Produces a fatal failure
     *
     * @param message A message describing the failure.
     * @return The result of a fatally failed output guardrail validation, blocking the evaluation of any other
     * subsequent validation.
     */
    public OutputGuardrailResult fatal(String message) {
        log.info("=======================fatal:{}", message + "====================");
        return null;
    }

    /**
     * Produces a fatal failure
     *
     * @param message A message describing the failure.
     * @param cause   The exception that caused this failure.
     * @return The result of a fatally failed output guardrail validation, blocking the evaluation of any other
     * subsequent validation.
     */
    public OutputGuardrailResult fatal(String message, Throwable cause) {
        log.info("=======================fatal:{}", message + "====================");
        return null;
    }

    /**
     * @param message A message describing the failure.
     * @return The result of a fatally failed output guardrail validation, blocking the evaluation of any other
     * subsequent validation and triggering a retry with the same user prompt.
     */
    public OutputGuardrailResult retry(String message) {
        log.info("=======================retry:{}", message + "====================");
        return null;
    }

    /**
     * @param message A message describing the failure.
     * @param cause   The exception that caused this failure.
     * @return The result of a fatally failed output guardrail validation, blocking the evaluation of any other
     * subsequent validation and triggering a retry with the same user prompt.
     */
    public OutputGuardrailResult retry(String message, Throwable cause) {
        log.info("=======================retry:{}", message + "====================");
        return null;
    }

    /**
     * @param message  A message describing the failure.
     * @param reprompt The new prompt to be used for the retry.
     * @return The result of a fatally failed output guardrail validation, blocking the evaluation of any other
     * subsequent validation and triggering a retry with a new user prompt.
     */
    public OutputGuardrailResult reprompt(String message, String reprompt) {
        log.info("=======================reprompt:{}", message + "====================");
        return null;
    }

    /**
     * @param message  A message describing the failure.
     * @param cause    The exception that caused this failure.
     * @param reprompt The new prompt to be used for the retry.
     * @return The result of a fatally failed output guardrail validation, blocking the evaluation of any other
     * subsequent validation and triggering a retry with a new user prompt.
     */
    public OutputGuardrailResult reprompt(String message, Throwable cause, String reprompt) {
        log.info("=======================reprompt:{}", message + "====================");
        return null;
    }

}
